package org.chaos.sekiro.workorder.app.form.internal.assemble

import org.chaos.sekiro.workorder.app.form.domain.component.Ability
import org.chaos.sekiro.workorder.app.form.domain.component.Attribute
import org.chaos.sekiro.workorder.app.form.domain.component.ComponentDomain
import org.chaos.sekiro.workorder.app.form.internal.model.*

fun assembleComponent(
    componentEntity: Component,
    abilityEntities: List<ComponentAbility>,
    componentBindAbilities: List<ComponentBindAbility>,
    attributeEntities: List<ComponentAttribute>,
    componentBindAttributes: List<ComponentBindAttribute>
): ComponentDomain {
    val idAbilityMap = abilityEntities.associateBy { it.id }
    val abilities = componentBindAbilities.filter{
        idAbilityMap.containsKey(it.abilityId)
    }.filter {
        componentEntity.id == it.componentId
    }.map {
        val abilityEntity = idAbilityMap[it.abilityId]!!
        buildAbility(abilityEntity, it)
    }

    val idAttributeMap = attributeEntities.associateBy { it.id }
    val attributes = componentBindAttributes.filter {
        idAttributeMap.containsKey(it.attributeId)
    }.filter {
        componentEntity.id == it.componentId
    }.map {
        val attributeEntity = idAttributeMap[it.attributeId]!!
        buildAttribute(attributeEntity, it)
    }

    return ComponentDomain(
        componentEntity.id!!,
        componentEntity.userId,
        componentEntity.formId,
        componentEntity.parentId,
        componentEntity.name,
        componentEntity.type,
        componentEntity.deleted,
        attributes,
        abilities
    )
}

fun buildAttribute(componentAttribute: ComponentAttribute, componentBindAttribute: ComponentBindAttribute) = Attribute(
    componentAttribute.code,
    componentAttribute.customCode,
    componentAttribute.name,
    componentBindAttribute.value
)

fun buildAbility(componentAbility: ComponentAbility, componentBindAbility: ComponentBindAbility) = Ability(
    componentAbility.code,
    componentAbility.customCode,
    componentAbility.name,
    componentBindAbility.value,
    componentBindAbility.enabled
)